import { Request, Response, NextFunction } from 'express';
import { prisma } from '../../config/database';
import { logger } from '../../utils/logger';
import { BaseController } from '../../utils/autoBind';
import { ResponseUtils } from '../../utils/responseUtils';
import { BUSINESS_ERROR_CODES, VALIDATION_ERROR_CODES } from '../../utils/errorCodes';

export class VoteController extends BaseController {
  // 获取投票统计
  async getVoteStatistics(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { startDate, endDate, artistId } = req.query;
      
      // 构建时间范围
      const dateFilter: any = {};
      if (startDate && endDate) {
        dateFilter.createdAt = {
          gte: new Date(startDate as string),
          lte: new Date(endDate as string)
        };
      }

      // 构建艺人过滤条件
      const artistFilter: any = {};
      if (artistId) {
        artistFilter.artistId = parseInt(artistId as string);
      }

      const [
        totalVotes,
        totalVoters,
        totalArtists,
        topArtists,
        dailyVotes,
        userVoteStats,
        artistVoteStats
      ] = await Promise.all([
        // 总投票数
        prisma.vote.count({
          where: {
            ...dateFilter,
            ...artistFilter
          }
        }),
        
        // 总投票用户数
        prisma.vote.groupBy({
          by: ['userId'],
          where: {
            ...dateFilter,
            ...artistFilter
          }
        }).then(result => result.length),
        
        // 参与投票的艺人数
        prisma.vote.groupBy({
          by: ['artistId'],
          where: {
            ...dateFilter,
            ...artistFilter
          }
        }).then(result => result.length),
        
        // 热门艺人排行
        prisma.vote.groupBy({
          by: ['artistId'],
          where: {
            ...dateFilter,
            ...artistFilter
          },
          _sum: {
            voteCount: true
          },
          orderBy: {
            _sum: {
              voteCount: 'desc'
            }
          },
          take: 10
        }),
        
        // 每日投票统计
        prisma.vote.groupBy({
          by: ['createdAt'],
          where: {
            ...dateFilter,
            ...artistFilter
          },
          _sum: {
            voteCount: true
          },
          orderBy: {
            createdAt: 'asc'
          }
        }),
        
        // 用户投票统计
        prisma.vote.groupBy({
          by: ['userId'],
          where: {
            ...dateFilter,
            ...artistFilter
          },
          _sum: {
            voteCount: true
          },
          orderBy: {
            _sum: {
              voteCount: 'desc'
            }
          },
          take: 10
        }),
        
        // 艺人投票统计
        prisma.vote.groupBy({
          by: ['artistId'],
          where: {
            ...dateFilter,
            ...artistFilter
          },
          _sum: {
            voteCount: true
          },
          _count: {
            userId: true
          },
          orderBy: {
            _sum: {
              voteCount: 'desc'
            }
          }
        })
      ]);

      // 获取艺人详细信息
      const topArtistsWithDetails = await Promise.all(
        topArtists.map(async (artist) => {
          const artistDetails = await prisma.artist.findUnique({
            where: { id: artist.artistId },
            select: {
              id: true,
              name: true,
              avatar: true
            }
          });
          
          return {
            artistId: artist.artistId,
            artist: artistDetails,
            totalVotes: artist._sum.voteCount || 0
          };
        })
      );

      // 获取用户详细信息
      const userVoteStatsWithDetails = await Promise.all(
        userVoteStats.map(async (user) => {
          const userDetails = await prisma.user.findUnique({
            where: { id: user.userId },
            select: {
              id: true,
              username: true,
              realName: true,
              avatar: true
            }
          });
          
          return {
            userId: user.userId,
            user: userDetails,
            totalVotes: user._sum.voteCount || 0
          };
        })
      );

      // 获取艺人详细信息
      const artistVoteStatsWithDetails = await Promise.all(
        artistVoteStats.map(async (artist) => {
          const artistDetails = await prisma.artist.findUnique({
            where: { id: artist.artistId },
            select: {
              id: true,
              name: true,
              avatar: true
            }
          });
          
          return {
            artistId: artist.artistId,
            artist: artistDetails,
            totalVotes: artist._sum.voteCount || 0,
            voterCount: artist._count.userId
          };
        })
      );

      const statistics = {
        overview: {
          totalVotes,
          totalVoters,
          totalArtists
        },
        topArtists: topArtistsWithDetails,
        dailyVotes: dailyVotes.map(stat => ({
          date: stat.createdAt.toISOString().split('T')[0],
          votes: stat._sum.voteCount || 0
        })),
        topVoters: userVoteStatsWithDetails,
        artistStats: artistVoteStatsWithDetails
      };

      ResponseUtils.success(res, statistics, '获取投票统计成功');
    } catch (error) {
      next(error);
    }
  }

  // 重置投票数据
  async resetVotes(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { artistId } = req.body;

      if (artistId) {
        // 重置指定艺人的投票
        const artist = await prisma.artist.findUnique({
          where: { id: parseInt(artistId) }
        });

        if (!artist) {
          ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.RESOURCE_NOT_FOUND, '艺人不存在');
          return;
        }

        await prisma.vote.deleteMany({
          where: { artistId: parseInt(artistId) }
        });

        logger.info(`重置艺人投票数据成功: ${artist.name} (ID: ${artistId})`);
        ResponseUtils.success(res, null, `已重置艺人"${artist.name}"的所有投票数据`);
      } else {
        // 重置所有投票
        await prisma.vote.deleteMany({});

        logger.info('重置所有投票数据成功');
        ResponseUtils.success(res, null, '已重置所有投票数据');
      }
    } catch (error) {
      next(error);
    }
  }

  // 获取投票详情列表
  async getVotes(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { page = 1, limit = 20, artistId, userId } = req.query;
      const pageNum = parseInt(page as string);
      const limitNum = parseInt(limit as string);
      const skip = (pageNum - 1) * limitNum;

      // 构建查询条件
      const where: any = {};
      let artistIdInt = parseInt(artistId as string);
      let userIdInt = parseInt(userId as string);
      if (artistId && isNaN(artistIdInt)) {
        logger.info(`查询艺人ID: ${artistId}`);
        where.artistId = artistIdInt;
      }
      
      if (userId && isNaN(userIdInt)) {
        logger.info(`查询用户ID: ${userId}`);
        where.userId = userIdInt;
      }

      // 查询投票列表
      const [votes, total] = await Promise.all([
        prisma.vote.findMany({
          where,
          skip,
          take: limitNum,
          orderBy: { createdAt: 'desc' },
          include: {
            user: {
              select: {
                id: true,
                username: true,
                realName: true,
                avatar: true
              }
            },
            artist: {
              select: {
                id: true,
                name: true,
                avatar: true
              }
            }
          }
        }),
        prisma.vote.count({ where })
      ]);

      ResponseUtils.paginated(res, votes, total, pageNum, limitNum, '获取投票列表成功');
    } catch (error) {
      next(error);
    }
  }

  // 删除投票记录
  async deleteVote(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { id } = req.params;
      const voteId = parseInt(id);

      if (isNaN(voteId)) {
        ResponseUtils.sendError(res, VALIDATION_ERROR_CODES.FIELD_TYPE_ERROR, '无效的投票ID');
        return;
      }

      // 检查投票是否存在
      const vote = await prisma.vote.findUnique({
        where: { id: voteId }
      });

      if (!vote) {
        ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.VOTE_NOT_FOUND, '投票记录不存在');
        return;
      }

      await prisma.vote.delete({
        where: { id: voteId }
      });

      logger.info(`投票记录删除成功: ID ${voteId}`);
      ResponseUtils.deleted(res, '删除投票记录成功');
    } catch (error) {
      next(error);
    }
  }
} 